import { GameConst } from "../constant/GameConst";
import Core from "../Core";
import { getNowMillisecond } from "../utils/TimeUtils";
import EquipModel from "./EquipModel";
import HeroModel from "./HeroModel";
import ModelBase from "./ModelBase";

// ===== 枚举 =====
export enum ModelType {
  HeroModel = "HeroInfo",
  EquipModel = "EquipModel",
}

// 唯一需要手动维护的映射表（但结构统一，易维护）
const ModelClasses = {
  [ModelType.EquipModel]: EquipModel,
  [ModelType.HeroModel]: HeroModel,
} as const; // 加 `as const` 更安全

// 自动推导实例类型映射
type ModelMapType = {
  [K in ModelType]: InstanceType<(typeof ModelClasses)[K]>;
};

// 自动创建实例注册表
const ModelRegistry = new Map<ModelType, ModelBase>(
  Object.values(ModelType).map((type) => {
    const Constructor = (ModelClasses as any)[type];
    return [type, new Constructor()];
  })
);

export default class Model {
  // 创建游戏数据模型实例
  private static _lastsvaetime: number = 0;

  /**
   * 根据 ModelType 获取对应类型的实例，自动推导返回类型
   */
  public static get<T extends ModelType>(type: T): ModelMapType[T] | undefined {
    return ModelRegistry.get(type) as ModelMapType[T];
  }

  public static init() {
    let localData = cc.sys.localStorage.getItem(GameConst.LOCAL_DATA_KEY);
    if (!localData) {
      // 首次登录，本地没有数据，则初始化数据
      console.info("首次登录，初始化本地数据");
      ModelRegistry.forEach((v, k, m) => {
        v.init();
      });
      //保存数据
      Model.save();
    } else {
      //非首次登录，则读取本地数据
      console.info("加载本地数据");
      localData = JSON.parse(localData);
      console.info(localData);
      //加载各个模块数据
      ModelRegistry.forEach((v, k, m) => {
        v.readData(localData);
      });
    }
    ModelRegistry.forEach((v, k, m) => {
      v.start();
    });
  }

  // 保存游戏数据
  public static save() {
    let gameData = {};
    ModelRegistry.forEach((v, k, m) => {
      v.writeData(gameData);
    });
    Model.saveData(gameData);
  }

  //保存数据
  private static saveData(localdata: any) {
    let now = Date.now();
    if (now - Model._lastsvaetime < 1000) {
      console.warn("❌ 保存太频繁：失败");
      return;
    }
    Model._lastsvaetime = now;
    this.saveLocal(localdata);
    console.info("🎉 数据保存成功");
  }

  //数据本地持久化
  private static saveLocal(data) {
    var strdata = JSON.stringify(data);
    cc.sys.localStorage.setItem(GameConst.LOCAL_DATA_KEY, strdata);
    //记录玩家最后一次保存时间
    this.get(ModelType.HeroModel).lastSaveTime = getNowMillisecond();
  }

  //清除本地记录
  static clearLocal() {
    cc.sys.localStorage.removeItem(GameConst.LOCAL_DATA_KEY);
  }

  //保存
  public static saveOffTimestamp() {
    cc.sys.localStorage.setItem(GameConst.LOCAL_OFFLINE_KEY, Date.now());
  }

  //加载
  public static getOffTimestamp() {
    let value = cc.sys.localStorage.getItem(GameConst.LOCAL_OFFLINE_KEY);
    return parseInt(value ? value : 0, 10);
  }
}
